import Vue from 'vue'
import constant from './const'
import DT from './DataHandler'
import Storage from './localStorage'
import Sound from './sound'
import { UploadLight } from "./UploadLight";

/**
 * 是否登录态
 */
import router from '../router'

Vue.prototype.DT = DT
Vue.prototype.Storage = Storage
Vue.prototype.API = constant.API
Vue.prototype.CONST = constant.CONST
Vue.prototype.Sound = Sound
Vue.prototype.UploadLight = UploadLight

window.Vue = Vue // global mount Vue
let alphaHub = new Vue() // global set Vue eventHub
window.alphaHub = alphaHub;
Vue.config.productionTip = true
Vue.config.errorHandler = (err, vm, info) => {
  console.error('------catch error by vue errorHandler------')
  console.error(err)
  console.error(vm)
  console.error(info)
  console.error('------///////////////////////////------')
}

Vue.prototype.isLogin = function (auto_redict = true) {
  let cookiekey = Vue.prototype.getCookie('cookiekey');
  if (auto_redict && !cookiekey) {
    router.push({ name: "register" })
  }
  return cookiekey ? true : false;
}

/**
 * 格式化时间
 */
Vue.prototype.formatDate = function (format, dt = null) {
  let date = new Date((typeof dt) === 'string' ? dt.replace(/-/g, '/') : dt)
  let y = date.getFullYear();
  let m = _pad(date.getMonth() + 1);
  let d = _pad(date.getDate());
  let hh = _pad(date.getHours());
  let mm = _pad(date.getMinutes());
  let ss = _pad(date.getSeconds());
  let fmt = format
    .replace('Y', y)
    .replace('M', m)
    .replace('D', d)
    .replace('hh', hh)
    .replace('mm', mm)
    .replace('ss', ss)
  let timeStr = y + '年' + m + '月' + d + '天' + hh + '时' + mm + '分' + ss + '秒'
  return { fmt, y, m, d, hh, mm, ss, timeStr }
}

/**
 * 获取数据类型
 * @param data
 * @returns {string}
 */
var dataType = function (data) {
  var getType = Object.prototype.toString
  var myType = getType.call(data) // 调用call方法判断类型，结果返回形如[object Function]
  var typeName = myType.slice(8, -1) // [object Function],即取除了“[object ”的字符串。
  return typeName
}

Vue.prototype.telReg = /^1(2|3|4|5|6|7|8|9)\d{9}$/

/** 读取cookies  */
Vue.prototype.getCookie = function (name) {
  var arr
  var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')
  if ((arr = document.cookie.match(reg))) return arr[2]
  else return ''
}

/** 写cookies */
Vue.prototype.setCookie = function (name, value, days = 15) {
  var exp = new Date()
  exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000)
  document.cookie = name + '=' + value + ';expires=' + exp.toUTCString()
}

/** 千分位 */
Vue.prototype.format_number = function (n) {
  if (!n) {
    return 0
  }
  let parts = n.toString().split('.')
  let b = parts[0]
  let len = b.length
  if (len <= 3) {
    return n
  }
  let r = len % 3
  let fmtB = r > 0
    ? b.slice(0, r) +
    ',' +
    b
      .slice(r, len)
      .match(/\d{3}/g)
      .join(',')
    : b
      .slice(r, len)
      .match(/\d{3}/g)
      .join(',')
  return `${fmtB}${parts.length > 1 ? '.' + parts[1] : ''}`
}

/** 获取URL参数 */
Vue.prototype.getUrlParam = function (param, url = window.location.href) {
  let reg = new RegExp('(^|&)' + param + '=([^&]*)(&|$)')
  let queries = url.split('?')[1] + ''
  let r = queries.match(reg)
  if (r != null) return decodeURI(r[2]) // 对encodeURI编码处理过的uri进行解码
  return null
}

Vue.prototype.getUrlParams = (str) => {
  let q = {}
  str.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => q[k] = v)
  return q
}

var isIphone = () => {
  let agent = window.navigator.userAgent
  if (agent.indexOf('iPhone') != -1) {
    return true
  }
  return false
}

Vue.prototype.copyIt = function (val) {
  val = val + ''
  const input = document.createElement('input')
  input.setAttribute('value', val)
  input.setAttribute('readonly', 'readonly')
  document.body.appendChild(input)
  // 必须执行了select 或 setSelectionRange 后 document.execCommand("copy") 才会有效。
  if (input.select() && document.execCommand('copy')) {
    // 支持 select()
    alphaHub.showToast({ msg: '内容已复制到粘贴板.' })
    document.execCommand('Copy', 'false', null)
  } else {
    // 不支持 select()
    alphaHub.showToast({ msg: '内容已复制到粘贴板!' })
    input.setSelectionRange(0, val.length)
    document.execCommand('Copy', 'false', null)
  }

  document.body.removeChild(input)
}

/**
 * 未通过geetest验证提示
 */
Vue.prototype.unGeetestTip = function () {
  alphaHub.showToast({ msg: '网络不给力，请刷新后重试' })
}

/**
 * app下载及百度追踪统计下载情况
 */
Vue.prototype.trackDownload = function (android_url) {
  let app_type = isIphone() ? 'ios' : 'android'
  console.log('trackDownload appType:', app_type)
  if (app_type == 'ios') {
    _hmt && _hmt.push(['_trackEvent', 'software', 'download', 'LUCY翻牌子-ios-pre'])
    router.push({ name: 'iosDownloadPre' })
  } else {
    _hmt && _hmt.push(['_trackEvent', 'software', 'download', 'LUCY翻牌子-android'])
    window.open(android_url)
    // let link = document.createElement('a');
    // link.setAttribute("href", android_url + '?go=true');
    // link.setAttribute("download", "LUCY.apk");
    // link.style.visibility = 'hidden';
    // document.body.appendChild(link);
    // link.click();
    // document.body.removeChild(link);
  }
}

/**
 * 获取极验证form数据
 */
Vue.prototype.getGeetestData = function () {
  let geeFrom = document.getElementsByClassName('geetest_form')[0]
  let inputs = geeFrom.getElementsByTagName('input')
  let values = {}
  for (var j = 0; j < inputs.length; j++) {
    values[inputs[j]['name']] = inputs[j]['value']
  }
  return {}
}

/**
 * {
 *  act:"",run：立即执行倒计时 check：检查并决定是否倒计时
 *  limit:"",//倒计时起点
 * }
 */
Vue.prototype.countDownRT = function ({
  act,
  limit = 60,
  localKey = 'msg_ct_unix',
  context = this
}) {
  let ticker = null
  let runCountDown = function () {
    if (context.rtCount > 0) {
      context.rtCount = limit - diffSecFun()
    } else {
      clearInterval(ticker)
      window.localStorage.removeItem(localKey)
      context.isCounting = false
      context.rtCount = 0
      alphaHub.$emit('reset_geetest')
    }
  }
  let diffSecFun = function () {
    let pastUnix = window.localStorage.getItem(localKey) || 0
    let currUnix = +new Date()
    let diffSec = Math.floor((currUnix - pastUnix) / 1000)
    // console.log("diffSecFun:", diffSec);
    return diffSec
  }

  // main
  if (act == 'run') {
    context.isCounting = true
    context.rtCount = limit
    window.localStorage.setItem(localKey, +new Date())
    ticker = setInterval(runCountDown, 1000)
  } else {
    let pastUnix = window.localStorage.getItem(localKey) || null
    // 已有倒计时记录
    if (pastUnix) {
      let diffSec = diffSecFun()
      // 仍在倒计时限制内（需要继续倒计时）
      if (diffSec < limit) {
        context.isCounting = true
        context.rtCount = limit - diffSec
        ticker = setInterval(runCountDown, 1000)
      } else {
        window.localStorage.removeItem(localKey)
      }
    }
  }
}


Vue.prototype.calcPercentAndCountDown = function (fromUnix, toUnix) {
  let percent = 0, countDownDesByDay, countDownDes;
  let currUnix = +new Date();
  //进度达到100%
  if (currUnix >= toUnix) {
    return {
      done: true,
      percent: 100,
      countDownDes: '00:00:00',
      countDownDesByDay: '0T 00:00:00',
      dateObj: {
        days: '00',
        hours: '00',
        minutes: '00',
        seconds: '00',
      }
    }
  }

  //计算进度（此处百分比精确到一位小数，与时间倒计时相比会有些许误差）
  let son = currUnix - fromUnix;
  let mother = toUnix - fromUnix;
  percent = Math.round(son / mother * 100 * 100) / 100;

  //计算倒计时
  let diffMs = toUnix - currUnix;
  let day = Math.floor(diffMs / 1000 / 60 / 60 / 24);
  let hour = Math.floor(diffMs / (1000 * 60 * 60)) % 24;
  let min = Math.floor(diffMs / (1000 * 60)) % 60;
  let sec = Math.floor(diffMs / 1000 % 60);
  let ms = Math.floor(diffMs / 1000 % 1000);
  let hours = day * 24 + hour;

  countDownDesByDay = `${day}T ${fixZero(hour)}:${fixZero(min)}:${fixZero(sec)}`
  countDownDes = `${fixZero(hours)}:${fixZero(min)}:${fixZero(sec)}`

  return {
    done: false,
    percent,
    countDownDesByDay,
    countDownDes,
    dateObj: {
      days: fixZero(day),
      hours: fixZero(hour),
      minutes: fixZero(min),
      seconds: _pad(sec),
    }
  };
}

Vue.prototype.verifyData = function (verData) {
  const { key, rules, dataObj } = verData
  if (typeof key !== 'string') {
    let count = 0
    for (let i = 0; i < key.length; i++) {
      let theKey = key[i]
      let data = dataObj[theKey]
      let regExp = rules[theKey]['reg_exp']
      let errMsg = rules[theKey]['err_msg']
      console.log(theKey, data, regExp, errMsg)
      if (regExp.test(data)) {
        count++
        continue
      }
      alphaHub.showToast({ msg: errMsg })
      break
    }
    if (count < key.length) {
      console.log('failed')
      return false
    } else {
      console.log('passed')
      return true
    }
  } else {
    let data = dataObj[key]
    let regExp = rules[key]['reg_exp']
    let errMsg = rules[key]['err_msg']
    // console.log(data,regExp,errMsg)
    if (regExp.test(data)) {
      return true
    }
    alphaHub.showToast({ msg: errMsg })
    return false
  }
}

function _pad(value) {
  return ('0' + value).slice(-2)
}

function fixZero(num) {
  return num < 10 ? `0${num}` : num + ''
}

function rgbToHex(r, g, b, a = '') {
  return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}${a}`
}

/** 手机号码用空格分割 */
var telFormat = function (tel) {
  tel = tel + ''
  // 方式一
  return tel.replace(/(\d{3})(\d{4})(\d{4})/, (rs, $1, $2, $3) => {
    return $1 + ' ' + $2 + ' ' + $3
  })
  // 方式二
  return tel.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3')
}

/** 手机号码隐藏中间部分 */
var telSecrect = function (tel) {
  if (!tel) {
    return ''
  }
  tel = tel + ''
  var sliceNumber = tel.slice(3, tel.length - 4)
  var newPhone = tel.replace(new RegExp(sliceNumber, 'g'), '****')
  // console.log(newPhone); //181****678
  return newPhone
}

Vue.prototype.randomRange = function (minNum, maxNum) {
  return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum)
}

/**
 * 小数乘法 精度处理
 * m,n,accurancy 乘数，被乘数，小数点精度
 */
Vue.prototype.decimalMuti = function (m, n, accurancy) {
  let acc = Math.pow(10, accurancy)
  return Math.round(m * n * acc) / acc
}

Vue.prototype.decimalDivision = function (m, n, accurancy) {
  let acc = Math.pow(10, accurancy)
  return (Math.round(m / n * acc) / acc)
}

Vue.prototype.decimalDevide = function (m, n, accurancy) {
  let acc = Math.pow(10, accurancy)
  return Math.round((m - n) * acc) / acc
}

Vue.prototype.decimalAdd = function (m, n, accurancy) {
  let acc = Math.pow(10, accurancy)
  return Math.round((m + n) * acc) / acc
}

Vue.prototype.startLoading = function () {
  alphaHub.$emit('display')
}

Vue.prototype.stopLoading = function () {
  alphaHub.$emit('hide')
}

Vue.prototype.showToast = function (data) {
  alphaHub.$emit('showToast', data)
}

Vue.prototype.hideToast = function () {
  alphaHub.$emit('hideToast')
}

Vue.prototype.showAlert = function (data) {
  alphaHub.$emit('showAlert', data)
}

Vue.prototype.hideAlert = function (reload = false) {
  alphaHub.$emit('hideAlert', reload)
}

Vue.prototype.showPass = function () {
  alphaHub.$emit('showPass')
}

Vue.prototype.hidePass = function () {
  alphaHub.$emit('hidePass')
}

/**
 * 处理滑动到底加载更多
 */
Vue.prototype.getScrollTop = function (domID) {
  let dom = document.getElementById(domID)
  return dom.scrollTop
}
Vue.prototype.getClientHeight = function (domID) {
  let dom = document.getElementById(domID)
  return dom.clientHeight
}
Vue.prototype.getScrollHeight = function (domID) {
  let dom = document.getElementById(domID)
  return dom.scrollHeight
}
Vue.prototype.reachBottom = function (domID, asset = 10) {
  let dom = document.getElementById(domID)
  return dom.scrollTop + dom.clientHeight >= dom.scrollHeight - asset
}

/**
 * IE/Safari不支持XXXX
 * 触底加载更多-IntersectionObserver实现
 * [targets][string|array]
 * [cb][function]
 * [options][object]
 * io.observe(dom)
 * io.unobserve(dom);
 * io.disconnect();
 */
Vue.prototype.reachBottomIO = function (targets, cb, options = {}) {
  // 创建监听器
  let io = new IntersectionObserver(entries => {
    cb && cb(entries[0].intersectionRatio > 0)
  }, options)

  // 开始监听目标元素
  if (typeof targets === 'object' && targets.length > 0) {
    targets.map(target => {
      io.observe(document.querySelector(target))
    })
  } else if (typeof targets === 'string') {
    io.observe(document.querySelector(targets))
  } else {
    alert('无监听对象或参数有误')
    return null
  }
}

/**
 * 页面跳转
 */
Vue.prototype.pageJump = function (name, query = {}) {
  router.push({ name, query })
}

window.rgbToHex = rgbToHex
Vue.prototype._pad = _pad
Vue.prototype.fixZero = fixZero
Vue.prototype.rgbToHex = rgbToHex
Vue.prototype.telFormat = telFormat
Vue.prototype.telSecrect = telSecrect
Vue.prototype.isIphone = isIphone
Vue.prototype.dataType = dataType
